var AccessApp = function()
{
	this.createdbfile = function(provided_filename)
	{
		var app = new ActiveXObject("Access.Application");
		var cdb = app.NewCurrentDatabase(provided_filename);
		app.Quit();
	}
}
var AccessClient = function(provided_filename)
{
	this.filename = provided_filename;
	this.mynetwork = new MyNetwork();
	var dtu = new DateTimeUtil();
	var dtstr = dtu.yearstr + dtu.monthstr + dtu.daystr + dtu.hourstr + dtu.minutestr + dtu.secondstr + dtu.millisecondstr;
	var fu = new FileUtil();
	var ft = dtstr + ".log";
	this.logfolderpath = fu.gettempfolderpath() + "\\acc";
	fu.createfolder(this.logfolderpath);
	this.logfilename = this.logfolderpath + "\\" + ft;
	var schemafilename = this.logfolderpath + "\\schema.ini";
	var schemacont = "[" + ft + "]" + "\n";
	schemacont += "ColNameHeader=False\n";
	schemacont += "MaxScanRows=0\n";
	schemacont += "CharacterSet=OEM\n";
	schemacont += "Format=TabDelimited\n";
	schemacont += "Col1=DT Text Width 255\n";
	schemacont += "Col2=ComputerName Text Width 255\n";
	schemacont += "Col3=UserName Text Width 255\n";
	schemacont += "Col4=LogFileName Text Width 255\n";
	schemacont += "Col5=FileName Text Width 255\n";
	schemacont += "Col6=Operation Text Width 255\n";
	schemacont += "Col7=Message Memo\n";
	fu.appendfile(schemafilename, schemacont);

	this.addlog = function(provided_op, provided_message)
	{
		var dtu = new DateTimeUtil();
		var dtstr = dtu.yearstr + dtu.monthstr + dtu.daystr + dtu.hourstr + dtu.minutestr + dtu.secondstr + dtu.millisecondstr;
		var op = provided_op;
		var line = dtstr + "\t" + this.mynetwork.computername.toUpperCase() + "\t" + this.mynetwork.username.toUpperCase() + "\t" + this.logfilename + "\t" + this.filename + "\t" + op + "\t" + provided_message;
		(new FileUtil()).appendfile(this.logfilename, line);
	}

	this.addlog("InstanceCreated", "");

	this.txnsqll = new Array();
	this.txnsqll.length = 0;
	this.txnmode = false;
	this.commandtimeout = 120;
	this.connectiontimeout = 15;
	this.schemaenum = new SchemaEnum();

	if(!(new FileUtil()).fileexists(provided_filename))
	{
		(new AccessApp()).createdbfile(provided_filename);
	}
	this.provider = "Microsoft.Ace.OLEDB.12.0";
	this.connstr = "Provider=" + this.provider + ";Data Source=" + this.filename;
	switch((new FileUtil()).fso.GetExtensionName(this.filename).toUpperCase())
	{
		case "CSV":
			{
				var fu = new FileUtil();
				this.connstr = "Provider=" + this.provider + ";Data Source=" + fu.fso.GetParentName(this.filename) + ";Extended Properties=TEXT";
				break;
			}
		case "SQLSERVER":
			{
				var fel = this.filename.split("\.");
				var servername = fel[0];
				var databasename = fel[1];
				this.connstr = "driver=sql server;server=" + servername + ";initial catalog=" + databasename;
				break;
			}
		default:
			{
				break;
			}
	}
	this.addlog("ConnectionStringGenerated", this.connstr);
	this.conn = null;
	this.openconn = function(provided_write)
	{
		this.addlog("ConnectionOpening", "WriteNode=" + provided_write + " " + this.connstr);
		this.conn = new ActiveXObject("ADODB.Connection");
		this.conn.Mode = 1;
		if(provided_write)
		{
			this.conn.Mode = 2;
		}
		this.conn.CommandTimeout = this.commandtimeout;
		this.conn.ConnectionTimeout = this.connectiontimeout;
		this.conn.Open(this.connstr);
		this.addlog("ConnectionOpened", "WriteNode=" + provided_write + " " + this.connstr);
	}
	this.closeconn = function()
	{
		this.addlog("ConnectionClosing", this.connstr);
		try{this.conn.Close();}catch(e){}
		this.addlog("ConnectionClosed", this.connstr);
	}
	this.begintrans = function()
	{
		this.txnmode = true;
		this.txnsqll.length = 0;
		this.addlog("TransactionBegan", "");
	}
	this.committrans = function()
	{
		this.addlog("TransactionExecuting", "transaction count=" + this.txnsqll.length.toString());
		var ret = true;
		this.openconn(true);
		this.conn.BeginTrans();
		try
		{
			for(var icnt = 0; icnt < this.txnsqll.length; icnt++)
			{
				var tempsql = this.txnsqll[icnt];
				this.addlog("TransactionSQL " + (icnt + 1).toString() + "/" + this.txnsqll.length.toString(), tempsql);
				this.conn.Execute(tempsql);
			}
			this.conn.CommitTrans();
		}
		catch(e)
		{
			ret = false;
			this.conn.RollbackTrans();
			for(var jcnt = 0; jcnt < this.txnsqll.length; jcnt++)
			{
				this.addlog("TransactionRollback " + (jcnt + 1).toString() + "/" + this.txnsqll.length.toString(), this.txnsqll[jcnt]);
			}
		}
		this.closeconn();
		this.txnmode = false;
		this.addlog("TransactionEnded", "");
		return ret;
	}
	this.executenonquery = function(provided_sql)
	{
		var ret = true;
		if(this.txnmode)
		{
			this.txnsqll[this.txnsqll.length] = provided_sql;
		}
		else
		{
			try
			{
				this.addlog("SQLExecution", provided_sql);
				this.openconn(true);
				this.conn.Execute(provided_sql);
				this.closeconn();
				this.addlog("SucceededSQLExecution", provided_sql);
			}
			catch(e)
			{
				this.addlog("FailedSQLExecution", provided_sql);
				messageout("file : " + this.filename + " failed to execute : " + provided_sql, "error", "AccessClient");
				debugout("file : " + this.filename + " failed to execute : " + provided_sql);
				ret = false;
			}
		}
		return ret;
	}
	this.rstoarray = function(rs)
	{
		var ret = new Array();
		ret.length = 0;
		if(!rs.EOF)
		{
			if(!rs.BOF)
			{
				rs.MoveFirst();
				while(!rs.EOF)
				{
					var tempr = new Array();
					tempr.length = 0;
					for(var icnt = 0; icnt < rs.Fields.Count; icnt++)
					{
						var nam = rs.Fields.Item(icnt).Name;
						var val = rs.Fields.Item(icnt).Value;
						tempr[nam] = val;
					}
					ret[ret.length] = tempr;
					rs.MoveNext();
				}
			}
		}
		return ret;
	}
	this.getschema = function(provided_criteria)
	{
		var mys = this.schemaenum.getitem("COLUMNS");
		if(provided_criteria)
		{
			mys = this.schemaenum.getitem(provided_criteria);
		}
		this.openconn();
		var rs = this.conn.OpenSchema(mys.value);
		var ret = this.rstoarray(rs);
		rs.Close();
		rs = null;
		this.closeconn();
		return ret;
	}
	this.executeselectquery = function(provided_sql)
	{
		this.openconn();
		this.addlog("SelectSQLExecution", provided_sql);
		var rs = this.conn.Execute(provided_sql);
		var ret = this.rstoarray(rs);
		rs.Close();
		rs = null;
		this.closeconn();
		return ret;
	}
	this.getschematohtml = function(provided_htmlfilename, provided_criteria)
	{
		var myh = document.createElement("html");
		var myb = myh.appendChild(document.createElement("body"));
		var mytable = this.createtablefromrl(this.getschema(provided_criteria));
		if(mytable)
		{
			myb.appendChild(mytable);
		}
		(new FileUtil()).writefile(provided_htmlfilename, myh.outerHTML);
	}
	this.executeselectquerytohtml = function(provided_sql, provided_htmlfilename)
	{
		var myh = document.createElement("html");
		var myb = myh.appendChild(document.createElement("body"));
		var mytable = this.createtablefromrl(this.executeselectquery(provided_sql));
		if(mytable)
		{
			myb.appendChild(mytable);
		}
		(new FileUtil()).writefile(provided_htmlfilename, myh.outerHTML);
	}
	this.createtablefromrl = function(provided_rl)
	{
		var ret = null;
		var rl = provided_rl;
		if(rl.length > 0)
		{
			var myt = document.createElement("table");
			var colelement = myt.appendChild(document.createElement("tr"));
			var coll = new Array();
			coll.length = 0;
			for(var fieldname in (rl[0]))
			{
				var coldataelement = colelement.appendChild(document.createElement("td"));
				coll[coll.length] = fieldname;
				coldataelement.innerText = fieldname;
			}

			for(var icnt = 0; icnt < rl.length; icnt++)
			{
				var myr = myt.appendChild(document.createElement("tr"));
				for(var jcnt = 0; jcnt < coll.length; jcnt++)
				{
					var colname = coll[jcnt];
					var myd = myr.appendChild(document.createElement("td"));
					myd.innerText = (rl[icnt])[colname];
				}
			}
			ret = myt;
		}
		return ret;
	}
}

var SchemaEnum = function()
{
	this.setup = function()
	{
		this.items = new Array();
		this.items.length = 0;

		this.items[this.items.length] = this.createitem("adSchemaAsserts", 0, "ASSERTIONS");
		this.items[this.items.length] = this.createitem("adSchemaCatalogs", 1, "CATALOGS");
		this.items[this.items.length] = this.createitem("adSchemaCharacterSets", 2, "CHARACTER_SETS");
		this.items[this.items.length] = this.createitem("adSchemaCheckConstraints", 5, "CHECK_CONSTRAINTS");
		this.items[this.items.length] = this.createitem("adSchemaCollations", 3, "COLLATIONS");
		this.items[this.items.length] = this.createitem("adSchemaColumns", 4, "COLUMNS");
		this.items[this.items.length] = this.createitem("adSchemaColumnsDomainUsage", 11, "COLUMN_DOMAIN_USAGE");
		this.items[this.items.length] = this.createitem("adSchemaColumnPrivileges", 13, "COLUMN_PRIVILEGES");
		this.items[this.items.length] = this.createitem("adSchemaConstraintColumnUsage", 6, "CONSTRAINT_COLUMN_USAGE");
		this.items[this.items.length] = this.createitem("adSchemaConstraintTableUsage", 7, "CONSTRAINT_TABLE_USAGE");
		this.items[this.items.length] = this.createitem("adSchemaCubes", 32, "CUBES");
		this.items[this.items.length] = this.createitem("adSchemaDimensions", 33, "DIMENSIONS");
		this.items[this.items.length] = this.createitem("adSchemaForeignKeys", 27, "FOREIGN_KEYS");
		this.items[this.items.length] = this.createitem("adSchemaHierarchies", 34, "HIERARCHIES");
		this.items[this.items.length] = this.createitem("adSchemaIndexes", 12, "INDEXES");
		this.items[this.items.length] = this.createitem("adSchemaDBInfoKeywords", 30, "KEYWORDS");
		this.items[this.items.length] = this.createitem("adSchemaKeyColumnUsage", 8, "KEY_COLUMN_USAGE");
		this.items[this.items.length] = this.createitem("adSchemaLevels", 35, "LEVELS");
		this.items[this.items.length] = this.createitem("adSchemaDBInfoLiterals", 31, "LITERALS");
		this.items[this.items.length] = this.createitem("adSchemaMeasures", 36, "MEASURES");
		this.items[this.items.length] = this.createitem("adSchemaMembers", 38, "MEMBERS");
		this.items[this.items.length] = this.createitem("adSchemaPrimaryKeys", 28, "PRIMARY_KEYS");
		this.items[this.items.length] = this.createitem("adSchemaProcedures", 16, "PROCEDURES");
		this.items[this.items.length] = this.createitem("adSchemaProcedureColumns", 29, "PROCEDURE_COLUMNS");
		this.items[this.items.length] = this.createitem("adSchemaProcedureParameters", 26, "PROCEDURE_PARAMETERS");
		this.items[this.items.length] = this.createitem("adSchemaProperties", 37, "PROPERTIES");
		this.items[this.items.length] = this.createitem("adSchemaProviderTypes", 22, "PROVIDER_TYPES");
		this.items[this.items.length] = this.createitem("AdSchemaReferentialConstraints", 9, "REFERENTIAL_CONSTRAINTS");
		this.items[this.items.length] = this.createitem("adSchemaSchemata", 17, "SCHEMATA");
		this.items[this.items.length] = this.createitem("adSchemaSQLLanguages", 18, "SQL_LANGUAGES");
		this.items[this.items.length] = this.createitem("adSchemaStatistics", 19, "STATISTICS");
		this.items[this.items.length] = this.createitem("adSchemaTables", 20, "TABLES");
		this.items[this.items.length] = this.createitem("adSchemaTableConstraints", 10, "TABLE_CONSTRAINTS");
		this.items[this.items.length] = this.createitem("adSchemaTablePrivileges", 14, "TABLE_PRIVILEGES");
		this.items[this.items.length] = this.createitem("adSchemaTranslations", 21, "TRANSLATIONS");
		this.items[this.items.length] = this.createitem("adSchemaUsagePrivileges", 15, "USAGE_PRIVILEGES");
		this.items[this.items.length] = this.createitem("adSchemaViews", 23, "VIEWS");
		this.items[this.items.length] = this.createitem("adSchemaViewColumnUsage", 24, "VIEW_COLUMN_USAGE");
		this.items[this.items.length] = this.createitem("adSchemaViewTableUsage", 25, "VIEW_TABLE_USAGE");
	}

	this.createitem = function(provided_name, provided_value, provided_alias)
	{
		var ret = new Array();
		ret.length = 0;
		ret.name = provided_name;
		ret.value = provided_value;
		ret.alias = provided_alias;
		return ret;
	}

	this.getitem = function(provided_data)
	{
		for(var icnt = 0; icnt < this.items.length; icnt++)
		{
			var tempe = this.items[icnt];
			for(var pn in tempe)
			{
				if(provided_data.toString().toUpperCase() == (tempe[pn]).toString().toUpperCase())
				{
					return tempe;
				}
			}
		}
		return null;
	}

	this.setup();
}
